/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pkgjeudestrategie;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.Integer;
import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.JPanel;
import pkgapplication.Sauvegarde;

/**
 *
 * @author Admin
 */
public class Jeu extends JPanel implements Serializable {

    int direction = -1;
    int nbPlayer;
    private Monde monde;
    //private Monde carte;
    int vbarPosition = 0;
    int hbarPosition = 0;
    boolean isMouse = false;
    EcranInfos informationScreen;
    EcranStats ecranStats;
    EscButton escButton;
    Fenetre fenetre;
    private ArrayList<Faction> listeFactions=null;
    private ArrayList<Player> listeJoueurs=null;
    private Terrain terrainClique;
    private int nZoom;
    private ArrayList<Terrain> listeTerrains=null;
    private int tourEnCours;
    private boolean newGame;
    Thread gameThread = new Thread() {

        @Override
        public void run() {
            while (true) {
                majJeu();
                repaint();
                revalidate();
                try {
                    Thread.sleep(10);
                } catch (InterruptedException ex) {
                }
            }
        }
    };

    public Jeu(EcranInfos informationScreen, int nbPlayer, EcranStats ecranStats, boolean newGame,Fenetre fenetre) {
        this.nbPlayer = nbPlayer;
        setFocusable(true);
        this.fenetre=fenetre;
        this.newGame = newGame;
        this.ecranStats = ecranStats;
        this.informationScreen = informationScreen;
        setSize(Fenetre.tailleX, Fenetre.tailleX);
        setLayout(null);

        if (newGame) {

            monde = new Monde(nbPlayer);







        } else {
            chargerSauvegardes();
System.out.println( listeTerrains.size());
            monde = new Monde(nbPlayer, listeJoueurs, listeFactions, listeTerrains);


        }
        this.informationScreen.setFactionList(monde.getFactionList());
            this.informationScreen.setPlayerList(monde.getPlayerList());
        //System.out.println(listeFactions + " " + listeJoueurs + " " + listeTerrains);



        setStartPosition(0);
        monde.setEcranStat(0, ecranStats);
        add(monde);


        gameThread.start();
        listen();






    }
public void setEscButton(EscButton escButton){
    this.escButton=escButton;
}
    public void majJeu() {
        int playerTurn=-1;
        if(monde.gameIsOn){
        playerTurn=informationScreen.getPlayerTurn();
            monde.setEcranStat(playerTurn, ecranStats);
            monde.seeDeadFactions();
            if(monde.relocate(playerTurn)){
                setStartPosition(playerTurn);
            }
        if (informationScreen.playerSwitch()) {
            setStartPosition(playerTurn);
            monde.doUpgrades();
            monde.hapinessCheck(playerTurn);
            if(informationScreen.isNewRealTurn()){
            monde.actualizeRecherche();
            monde.actualiserArgent();
            monde.actualizePopulation(playerTurn);
            
            }

            monde.setEcranStat(playerTurn, ecranStats);
            monde.setCleanClic(playerTurn, 0);

            monde.setHapiness(playerTurn);
            monde.setEcranStat(playerTurn,ecranStats);
            monde. setCleanClic(playerTurn,0);

        }
        if (informationScreen.getColonisedTerritoire() != null) {
            monde.colonise(informationScreen.getColonisedTerritoire(), playerTurn);
            informationScreen.setNullColonisedTerritoire();
        }
        informationScreen.getFicheButtonActivated();
        informationScreen.setStateClickedTerrain(monde.getClickedTerrainState());
        asCursorMoved();
        
        if(escButton!=null){
        int y0=escButton.isMoving();
        if(y0==0){
            
            setDirection(2,true);}
            else if(y0==1){
            setDirection(0,true);
            setDirection(2,true);}
            else if(y0==2){
            setDirection(0,true);
                
            }}
        int y1=ecranStats.isMoving();
        if(y1==0){
            
            setDirection(2,true);}
            else if(y1==1){
            setDirection(0,true);
            setDirection(2,true);}
            else if(y1==2){
            setDirection(0,true);
                
            }
        
        int y2=informationScreen.isMoving();
        if(y2!=-1){
           if(y2==0) {setDirection(1,true);
           setDirection(2,true);}
           else if(y2==1){
               setDirection(1,true);
               setDirection(3,true);
           }
           else if(y2==2){
               setDirection(2,true);
           }
           else if(y2==3){
               setDirection(1,true);
           }
           else if(y2==4){
               setDirection(3,true);
           }
            
        }
        repaint();}
        else{fenetre.restart();}
        int bomba=informationScreen.getBombardement();
        if(bomba!=-1){
                monde.bombardement(bomba,playerTurn,informationScreen.getTerrainClicked());
            informationScreen.resetBombardement();
        }
    }

    public void setDirection(int i, boolean b) {
        direction = i;
        if (b) {
            isMouse = true;
        } else {
            isMouse = false;
        }
        moveMonde();
    }

    public void asCursorMoved() {
        try {
            if (getMousePosition().getX() > (Fenetre.tailleX - 200) * 99 / 100) {
                setDirection(0, true); //droite
            }
            if (getMousePosition().getY() > Fenetre.tailleY * 99 / 100) {

                setDirection(3, true); //bas
            }
            if (getMousePosition().getY() < Fenetre.tailleY * 1 / 100) {

                setDirection(2, true); //haut
            }
        } catch (Exception e) {
        }

    }

    public void moveMonde() {
        int factor = 68;
        if (isMouse) {
            factor = 10;
        }
        if (direction == 0) {
            hbarPosition = hbarPosition - factor;
        } else if (direction == 1) {
            hbarPosition = hbarPosition + factor;
        } else if (direction == 2) {
            vbarPosition = vbarPosition + factor;
        } else if (direction == 3) {
            vbarPosition = vbarPosition - factor;
        }
        direction = -1;
        monde.setLocation(hbarPosition, vbarPosition);
    }
// 650:  h: -5008  v:  -5304
// 400:  h: -3156  v:  -3384
// 150:  h: -1312  v:  -1540

    public void setStartPosition(int nbPlayer) {
        int[] tab = monde.getCapitale(nbPlayer);

        this.informationScreen.setStateClickedTerrain(monde.getTerritoireCapital(nbPlayer));
        hbarPosition = (int) ((getWidth() - 200) / 2) - tab[0];
        vbarPosition = (int) (getHeight() / 4) - tab[1];
        monde.setLocation(hbarPosition, vbarPosition);
    }

    public int[] whichCentralisationFactor() {
        int[] tab = new int[4];
        int baseSize = monde.getNewSize();
        tab[0] = (-hbarPosition) + (int) ((getWidth() / 2) - (baseSize / 2));
        tab[1] = (-vbarPosition) + (int) ((getHeight() / 2) - (baseSize / 2));
        tab[2] = (int) (tab[0] / (baseSize));
        tab[3] = (int) (tab[1] / (baseSize));
        return tab;
    }

    public void zoom(int zoom) {
        boolean zoomB = false;
        int[] tab = whichCentralisationFactor();
        int n = monde.getN();
        if ((zoom < 0 && n < 4) || (zoom > 0 && n > -4)) {
            monde.zoom(zoom);
            zoomB = true;
            n = monde.getN();
        }
        int x = 0;
        int y = 0;
        // sa depend plus de la place que t'est dans la carte que de la grosseur de la carte`;...
        //grosso-modo, pour le monde que sa intéresse, j'ai fait deux diagonales à partir de
        //la proportion de la position et de la grosseur des cases, avec une valeur de 
        //déplacement (pour centrer) qui varie selon ladite proportion...

        switch (tab[2]) {
            case -1:
                x = -10;
                break;
            case 0:
                x = 0;
                break;
            case 1:
                x = 50;
                break;
            case 2:
                x = 100;
                break;
            case 3:
                x = 150;
                break;
            case 4:
                x = 225;
                break;
            case 5:
                x = 300;
                break;
            case 6:
                x = 350;
                break;
            case 7:
                x = 400;
                break;
            case 8:
                x = 450;
                break;
            case 9:
            case 10:
            case 11:
                x = 500;
                break;
            default:
                setStartPosition(informationScreen.getPlayerTurn());
                break;
        }
        switch (tab[3]) {
            case -1:
                y = -10;
                break;
            case 0:
                y = 0;
                break;
            case 1:
                y = 50;
                break;
            case 2:
                y = 100;
                break;
            case 3:
                y = 150;
                break;
            case 4:
                y = 225;
                break;
            case 5:
                y = 300;
                break;
            case 6:
                y = 350;
                break;
            case 7:
                y = 400;
                break;
            case 8:
                y = 450;
                break;
            case 9:
            case 10:
            case 11:
                y = 500;
                break;
            default:
                setStartPosition(informationScreen.getPlayerTurn());
                break;
            //si le joueur dépasse les proportions (0 à 10), on suppose qu'il est perdu (dans la mer)
        }
        if (zoom < 0 && n != 5) {
            x = -x;
            y = -y;
        } else if (zoom > 0 && n != -5) {
            x = x;
            y = y;
        } else {
            x = 0;
            y = 0;
        }
        // 150 => 3/4
        // 300 => 5/6
        // 400 => 7/8
        if (zoomB) {
            hbarPosition = hbarPosition + x;
            vbarPosition = vbarPosition + y;
            monde.setLocation(hbarPosition, vbarPosition);
        }

    }

    public void paintComponent(Graphics g) {
        g.setColor(Color.blue);
        g.fillRect(0, 0, 10000, 10000);
    }

    public Jeu getJeu() {
        return this;
    }

    public void listen() {
        this.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                    System.out.println("dbdb");

                    FenetreMenuEsc fenetreEscape = new FenetreMenuEsc((getJeu()));
                    fenetreEscape.requestFocus();


                }
                if (e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_D) {
                    setDirection(0, false);

                } else if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_A) {
                    setDirection(1, false);


                } else if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_W) {

                    setDirection(2, false);

                } else if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_S) {

                    setDirection(3, false);

                } else if (e.getKeyCode() == KeyEvent.VK_Z) {

                    zoom(-1);

                } else if (e.getKeyCode() == KeyEvent.VK_X) {

                    zoom(1);

                }
            }
        });
        this.addMouseWheelListener(new MouseWheelListener() {

            public void mouseWheelMoved(MouseWheelEvent e) {
                zoom(e.getWheelRotation());

            }
        });
    }

    public Monde getMonde() {
        return monde;
    }

    public void sauvegarder() {

        listeFactions = monde.getFactionList();
        listeJoueurs = monde.getPlayerList();
        Terrain terrainClique = monde.getClickedTerrainState();
        nZoom = monde.getN();
        listeTerrains = monde.getTerrainList();
        tourEnCours = informationScreen.getPlayerTurn();
        Sauvegarde sauvegarde = new Sauvegarde(listeFactions, listeJoueurs,
                terrainClique, nZoom, listeTerrains, tourEnCours);

        try {
            FileOutputStream fos =
                    new FileOutputStream("sauvegarde.dat");
            ObjectOutputStream oos = new ObjectOutputStream(fos);

            oos.writeObject(sauvegarde);
            oos.flush();
            oos.close();
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }

    }

    /*
     * Sert à charger une partie en lisant le fichier de sauvegarde
     */
    public void chargerSauvegardes() {
        try {
            FileInputStream fichier = new FileInputStream("sauvegarde.dat");
            ObjectInputStream ois = new ObjectInputStream(fichier);
            Sauvegarde sauvegarde = (Sauvegarde) ois.readObject();

            listeFactions = (ArrayList<Faction>) sauvegarde.getListeFactions();
            listeJoueurs = (ArrayList<Player>) sauvegarde.getListeJoueurs();
            listeTerrains = (ArrayList<Terrain>) sauvegarde.getListeTerrains();
            nZoom = (Integer) sauvegarde.getnZoom();
            tourEnCours = (Integer) sauvegarde.getTourEnCours();
            terrainClique = (Terrain) sauvegarde.getTerrainClique();



        } catch (java.io.IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public ArrayList<Faction> getListeFactions() {
        return listeFactions;
    }

    public ArrayList<Player> getListeJoueurs() {
        return listeJoueurs;
    }

    public ArrayList<Terrain> getListeTerrains() {
        return listeTerrains;
    }

    public int getnZoom() {
        return nZoom;
    }

    public int getTourEnCours() {
        return tourEnCours;
    }

    public Terrain getTerrainClique() {
        return terrainClique;
    }
}
